package com.jy.modules.cims.component.api;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.jy.modules.cims.common.CimsConstant;
import com.jy.modules.cims.common.CimsIrtUrlConstant;
import com.jy.modules.cims.common.JResult;
import com.jy.modules.cims.common.sysUtils.CollectionsUtils;
import com.jy.modules.cims.common.sysUtils.DateTimeUtils;
import com.jy.modules.cims.common.sysUtils.SearchParamUtil;
import com.jy.modules.cims.component.common.service.TCMmContractService;
import com.jy.modules.cims.component.common.service.TCMmCreditDetailService;
import com.jy.modules.cims.component.common.service.TCMmLoanDetailService;
import com.jy.modules.cims.component.loan.ICLoan;
import com.jy.modules.cims.component.loan.TBJCLoanImpl;
import com.jy.modules.cims.component.loan.ValidateLoanUtils;
import com.jy.modules.cims.component.quota.ICQuota;
import com.jy.modules.cims.component.sysAssist.JieYueApiAssist;
import com.jy.modules.cims.data.common.dto.TCMmCreditDetailDTO;
import com.jy.modules.cims.data.common.dto.TCMmLoanDetailDTO;
import com.jy.modules.cims.data.dao.DealDao;
import com.jy.modules.cims.data.dao.QuotaDao;
import com.jy.modules.cims.data.interact.api.ResponseMessageEnum;
import com.jy.modules.cims.data.interact.api.request.RequestAuditResultReceiveDTO;
import com.jy.modules.cims.data.interact.api.request.RequestLoanRedemptionApplyDTO;
import com.jy.modules.cims.data.interact.api.request.RequestLoanRedemptionApplyLoanDTO;
import com.jy.modules.cims.data.interact.api.request.RequestLoanResultReceiveDTO;
import com.jy.modules.cims.data.interact.api.response.ResponseAuditResultReceiveDTO;
import com.jy.modules.cims.data.interact.api.response.ResponseLoanRedemptionApplyDTO;
import com.jy.modules.cims.data.interact.api.response.ResponseLoanResultReceiveDTO;

/**
 * @description 捷越接受外围系统贷款业务处理组件。
 * @author shengzhoutao
 * 
 */
@Service("com.jy.modules.cims.component.api.CReceiveLoanImpl")
public class CReceiveLoanImpl {

	private static final Logger logger = LoggerFactory.getLogger(CReceiveLoanImpl.class);

	@Autowired
	@Qualifier("com.jy.modules.cims.component.common.service.TCMmContractService")
	public TCMmContractService tcMmContractService;

	@Autowired
	@Qualifier("com.jy.modules.cims.component.quota.CQuotaImpl")
	public ICQuota iCQuota;

	@Autowired
	public QuotaDao quotaDao;

	@Autowired
	public DealDao dealDao;

	@Autowired
	@Qualifier("com.jy.modules.cims.component.loan.TBJCLoanImpl")
	private TBJCLoanImpl tbjCLoanImpl;

	@Autowired
	@Qualifier("com.jy.modules.cims.component.loan.ValidateLoanUtils")
	private ValidateLoanUtils validateLoanUtils;

	@Autowired
	@Qualifier("com.jy.modules.cims.component.sysAssist.JieYueApiAssist")
	private JieYueApiAssist jieYueApiAssist;

	@Autowired
	@Qualifier("com.jy.modules.cims.component.loan.CLoanImpl")
	private ICLoan cLoan;

	@Autowired
	@Qualifier("com.jy.modules.cims.component.common.service.TCMmCreditDetailService")
	private TCMmCreditDetailService creditDetailService;

	@Autowired
	@Qualifier("com.jy.modules.cims.component.common.service.TCMmLoanDetailService")
	private TCMmLoanDetailService loanDetailService;

	/**
	 * @description 接受商户推送审批结果请求：接收商户系统债务人审核结果，并在合作机构系统保存债务人审核结果信息，
	 *              同时生成响应结果反馈给商户 。
	 * @param
	 * @return
	 * @throws Exception
	 * @author zhengchaoshuai/zhangmi
	 * @Date
	 */
	public ResponseAuditResultReceiveDTO dealAuditResult(final RequestAuditResultReceiveDTO content) throws Exception {
		logger.info("接收贷款审批结果==>>");
		ResponseAuditResultReceiveDTO response = new ResponseAuditResultReceiveDTO();

		String contractNo = content.getLoanNumber();
		String status = content.getResult();
		response.setId(contractNo);
		response.setResult(ResponseMessageEnum.FAILURE.getResult());

		// 状态校验
		JResult jResult = validateLoanUtils.validateAuditResultByLoanNumber(contractNo);
		if (!jResult.isSuccess()) {
			logger.info("合同号：【{}】贷款审批状态验证失败！【{}】", contractNo, jResult.getErrMsg());
			response.setMessage(jResult.getErrMsg());
			response.setId(contractNo);
			response.setResult(ResponseMessageEnum.FAILURE.getResult());
			return response;
		}
		// 审批中
		if (CimsConstant.JIEYUE_RESULT_API_DEFAULT.equals(status)) {
			logger.info("合同号：【{}】正在审批中！", contractNo);
			response.setResult(ResponseMessageEnum.SUCCESS.getResult());
			response.setMessage("审批中，不做处理！");
			// 审批成功！
		} else if (CimsConstant.JIEYUE_RESULT_API_AUDIT_SUCCESS.equals(status)) {
			tbjCLoanImpl.auditLoan(contractNo, CimsConstant.LOAN_EACH_STATUS_AUDIT, CimsConstant.LOAN_CONFIRM_WIN, null);
			tbjCLoanImpl.approveConfrim(contractNo, CimsIrtUrlConstant.IRT_LOAN_APPROVE_SUCCESS);

			logger.info("合同号：【{}】审批成功处理完成！", contractNo);
			response.setResult(ResponseMessageEnum.SUCCESS.getResult());
			response.setMessage("合同号：【" + contractNo + "】审批成功处理完成！");
			// 审批失败
		} else if (CimsConstant.JIEYUE_RESULT_API_AUDIT_REFUSE.equals(status)) {
			tbjCLoanImpl.auditLoan(contractNo, CimsConstant.LOAN_EACH_STATUS_AUDIT, CimsConstant.LOAN_CONFIRM_LOSE, null);
			tbjCLoanImpl.approveConfrim(contractNo, CimsIrtUrlConstant.IRT_LOAN_APPROVE_FAIL);

			logger.info("合同号：【{}】审批失败处理完成！", contractNo);
			response.setMessage("合同号：【" + contractNo + "】审批失败处理完成！");
			response.setResult(ResponseMessageEnum.SUCCESS.getResult());
			// 未能识别的状态
		} else {
			logger.info("合同号：【{}】处理失败！该审批状态未能识别！", contractNo);
			response.setResult(ResponseMessageEnum.FAILURE.getResult());
			response.setMessage("该审批状态未能识别！");
		}
		logger.info("<<==处理贷款审批结束");
		return response;
	}

	/**
	 * @description 接受商户推送放款结果请求：:接收商户系统放款结果，并在合作机构系统保存放款结果信息， 同时生成响应结果反馈给商户。
	 * @param
	 * @return
	 * @throws Exception
	 * @author zhengchaoshuai/zhangmi
	 * @Date
	 */
	public ResponseLoanResultReceiveDTO dealLoanResult(final RequestLoanResultReceiveDTO content) throws Exception {
		logger.info("接收贷款放款结果==>>");
		ResponseLoanResultReceiveDTO response = new ResponseLoanResultReceiveDTO();
		String contractNo = content.getLoanNumber();
		String status = content.getResult();
		Date dateTime = content.getEndTime();
		// String loanAmount = content.getLoanAmount();
		response.setId(contractNo);
		response.setResult(ResponseMessageEnum.FAILURE.getResult());
		// 状态校验
		JResult jResult = validateLoanUtils.validateLoanResultByLoanNumber(contractNo);
		if (!jResult.isSuccess()) {
			logger.info("合同号：【{}】贷款放款状态验证失败！【{}】", contractNo, jResult.getErrMsg());
			response.setMessage(jResult.getErrMsg());
			response.setId(contractNo);
			response.setResult(ResponseMessageEnum.FAILURE.getResult());
			return response;
		}
		// 放款中
		if (CimsConstant.JIEYUE_RESULT_API_DEFAULT.equals(status)) {
			logger.info("合同号：【{}】正在放款中！", contractNo);
			response.setResult(ResponseMessageEnum.SUCCESS.getResult());
			response.setMessage("放款中，不做处理！");
			// 放款成功！
		} else if (CimsConstant.JIEYUE_RESULT_API_LOAN_SUCCESS.equals(status)) {
			tbjCLoanImpl.loanFundOut(contractNo, CimsIrtUrlConstant.IRT_LOAN_FUNDOUT_SUCCESS, dateTime);
			tbjCLoanImpl.auditLoan(contractNo, CimsConstant.LOAN_EACH_STATUS_CORE, CimsConstant.LOAN_FUNDOUT_WIN, dateTime);
			tbjCLoanImpl.insertCreditByContractNo(contractNo, dateTime);

			logger.info("合同号：【{}】放款成功处理完成！", contractNo);
			response.setResult(ResponseMessageEnum.SUCCESS.getResult());
			response.setMessage("合同号：【" + contractNo + "】放款成功处理完成！");
			// 放款失败
		} else if (CimsConstant.JIEYUE_RESULT_API_LOAN_REFUSE.equals(status)) {
			tbjCLoanImpl.loanFundOut(contractNo, CimsIrtUrlConstant.IRT_LOAN_FUNDOUT_FAIL, dateTime);
			tbjCLoanImpl.auditLoan(contractNo, CimsConstant.LOAN_EACH_STATUS_CORE, CimsConstant.LOAN_FUNDOUT_LOSE, null);

			logger.info("合同号：【{}】放款失败处理完成！", contractNo);
			response.setMessage("合同号：【" + contractNo + "】放款失败处理完成！");
			response.setResult(ResponseMessageEnum.SUCCESS.getResult());
			// 未能识别的状态
		} else {
			logger.info("合同号：【{}】处理失败！该放款状态未能识别！", contractNo);
			response.setResult(ResponseMessageEnum.FAILURE.getResult());
			response.setMessage("该放款状态未能识别！");
		}
		logger.info("<<==处理贷款放款结束");
		return response;
	}

	/**
	 * @description 接受商户贷款回购申请请求
	 * @param content
	 *            请求主体内容
	 * @return response 响应信息
	 * @throws Exception
	 * @author shengzhoutao
	 * @Date
	 */
	public ResponseLoanRedemptionApplyDTO applyRedemption(final RequestLoanRedemptionApplyDTO content) throws Exception {
		ResponseLoanRedemptionApplyDTO response = new ResponseLoanRedemptionApplyDTO();
		List<RequestLoanRedemptionApplyLoanDTO> loanList = content.getLoanList();

		// 验证贷款回购申请请求
		JResult jResult = validateRedemption(loanList);
		if (jResult.isSuccess() == false) {
			response.setResult(ResponseMessageEnum.FAILURE.getResult());
			response.setMessage(jResult.getErrMsg());
			return response;
		}

		// 贷款回购处理
		String dealCode = cLoan.doReceiveLoanRedemption(content.getLoanList());
		response.setId(dealCode);// 申请成功返回的回购申请编号，该字段唯一.
		response.setResult(ResponseMessageEnum.SUCCESS.getResult());
		response.setMessage("回购申请交易成功！回购申请编号为:" + dealCode);

		return response;
	}

	/**
	 * 验证贷款回购申请请求
	 * 
	 * @param loanList
	 * @return JResult
	 * @author shengzhoutao
	 * @throws Exception
	 */
	JResult validateRedemption(final List<RequestLoanRedemptionApplyLoanDTO> loanList) throws Exception {
		JResult result = new JResult();
		result.setSuccess(false);

		if (CollectionsUtils.isEmpty(loanList)) {
			result.setErrCode(ResponseMessageEnum.FAILURE.getResult());
			result.setErrMsg("贷款列表不能为空");
			return result;
		}

		if (loanList.size() > 1000) {
			result.setErrMsg("贷款列表条数不能超过1000条以上");
			return result;
		}

		String error = null;
		for (RequestLoanRedemptionApplyLoanDTO loan : loanList) {
			error = jieYueApiAssist.validate(loan);
		}
		if (StringUtils.hasText(error)) {
			result.setErrMsg(error);
			return result;
		}

		Set<String> temp = new HashSet<String>();
		for (RequestLoanRedemptionApplyLoanDTO loan : loanList) {
			String redeemDateStr = DateTimeUtils.formatDate(loan.getRedeemDate(), DateTimeUtils.DEFAULT_DATE_FORMAT_2);
			temp.add(redeemDateStr);
		}
		if (temp.size() > 1) {
			result.setErrMsg("贷款列表的回购日期必须一致;");
			return result;
		}

		StringBuffer sb = new StringBuffer();
		TCMmCreditDetailDTO creditDetailDTO = null;
		TCMmLoanDetailDTO loanDetailDTO = null;
		for (RequestLoanRedemptionApplyLoanDTO loan : loanList) {
			String redeemDateStr = DateTimeUtils.formatDate(loan.getRedeemDate(), DateTimeUtils.DEFAULT_DATE_FORMAT_2);
			if (DateTimeUtils.dateCompare(loan.getRedeemDate(), new Date())) {
				error = java.text.MessageFormat.format("合同编号[{0}],回购日期[{1}]不能大于服务器日期[{2}];", new Object[] { loan.getLoanNumber(), redeemDateStr,
						DateTimeUtils.formatDate(new Date(), DateTimeUtils.DEFAULT_DATE_FORMAT_2) });
				sb.append(error);
			}

			if (loan.getMakeCreditorValue().compareTo(BigDecimal.ZERO) < 1) {
				sb.append(java.text.MessageFormat.format("合同编号[{0}],回购价格[{1}]不能小于或等于0;",
						new Object[] { loan.getLoanNumber(), loan.getMakeCreditorValue() }));
			}

			loanDetailDTO = new TCMmLoanDetailDTO();
			loanDetailDTO.setContractNo(loan.getLoanNumber());
			List<TCMmLoanDetailDTO> loanDetailList = loanDetailService.searchTCMmLoanDetail(SearchParamUtil.getSearchParam(loanDetailDTO));
			if (CollectionsUtils.isEmpty(loanDetailList)) {
				sb.append(java.text.MessageFormat.format("合同编号[{0}]不存在;", new Object[] { loan.getLoanNumber() }));
			} else {
				loanDetailDTO = loanDetailList.get(0);
				if (!CimsConstant.LOAN_FUNDOUT_WIN.equals(loanDetailDTO.getLoanStatus())) {
					sb.append(java.text.MessageFormat.format("合同编号[{0}]的贷款状态不符合回购要求;", new Object[] { loan.getLoanNumber() }));
				} else {
					creditDetailDTO = new TCMmCreditDetailDTO();
					creditDetailDTO.setTransferId(loan.getLoanNumber());
					creditDetailDTO.setCreditSource(CimsConstant.CREDIT_SOURCE_LOA);
					List<TCMmCreditDetailDTO> creditDetailList = creditDetailService.searchTCMmCreditDetail(SearchParamUtil
							.getSearchParam(creditDetailDTO));
					if (CollectionsUtils.isEmpty(creditDetailList)) {
						sb.append(java.text.MessageFormat.format("合同编号[{0}]不存在，或不符合回购要求;", new Object[] { loan.getLoanNumber() }));
					} else {
						creditDetailDTO = creditDetailList.get(0);
						if (CimsConstant.CREDIT_STATUS_RED.equals(creditDetailDTO.getCreditorStatus())) {
							sb.append(java.text.MessageFormat.format("合同编号[{0}]的已经回购成功，不可重复回购;", new Object[] { loan.getLoanNumber() }));
						}
					}
				}
			}
		}

		error = sb.toString();
		if (StringUtils.hasText(error)) {
			result.setErrMsg(error);
			return result;
		}

		result.setSuccess(true);
		return result;
	}
}
